package com.kevin.v2.spring.formework.webmvc.servlet.mvc;

import com.kevin.v1.springframework.annotation.KvRequestMapping;
import com.kevin.v1.springframework.annotation.KvRequestParam;
import com.kevin.v2.spring.formework.webmvc.servlet.KvHandlerMapping;
import com.kevin.v2.spring.formework.webmvc.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 用来做请求参数处理
 */
public class KvHandlerAdapter {

   public boolean supports (Object handler) {
      return (handler instanceof KvHandlerMapping);
   }

   public ModelAndView handle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      KvHandlerMapping handlerMapping = (KvHandlerMapping) handler;
      Map<String, Integer> paramIndexMap = new HashMap<>();

      //获取要访问方法加注解的所有形参 二维数组 第一维度是注解 第二维度是参数  可以看作X Y轴
      Annotation[][] parameterAnnotations = handlerMapping.getMethod().getParameterAnnotations();
      for (int i = 0; i < parameterAnnotations.length; i++) {
         for (Annotation parameterAnnotation : parameterAnnotations[i]) {
            if (parameterAnnotation instanceof KvRequestParam) {
               String paraName = ((KvRequestParam) parameterAnnotation).value();
               //参数名称 对应所在的下标
               paramIndexMap.put(paraName, i);
            }
         }
      }

      //查找 ServletRequest 和ServletResponce
      Class<?>[] paramTypes = handlerMapping.getMethod().getParameterTypes();
      for (int i = 0; i < paramTypes.length; i++) {
         if (paramTypes[i] == HttpServletRequest.class || paramTypes[i] == HttpServletResponse.class) {
            paramIndexMap.put(paramTypes[i].getName(), i);
         }
      }


      //获取request 里的参数
      Map<String, String[]> paramMaps = request.getParameterMap();

      //构造实参数组 用于调用方法时传递
      Object[] paramValues = new Object[paramTypes.length];

      for (Map.Entry<String, String[]> param : paramMaps.entrySet()) {
         String value = Arrays.toString(param.getValue()).replaceAll("\\[\\]", "").replaceAll("\\s", "");
         if (paramIndexMap.containsKey(param.getKey())) {
            int index = paramIndexMap.get(param.getKey());
            //强制类型转换后赋值
            paramValues[index] = caseStringValue(value,paramTypes[index]);
         }
      }

      if (paramIndexMap.containsKey(HttpServletRequest.class.getName())) {
         int index = paramIndexMap.get(HttpServletRequest.class.getName());
         paramValues[index] = request;
      }
      if (paramIndexMap.containsKey(HttpServletResponse.class.getName())) {
         int index = paramIndexMap.get(HttpServletResponse.class.getName());
         paramValues[index] = response;
      }
      Object object = handlerMapping.getMethod().invoke(handlerMapping.getController(), paramValues);
      if (handlerMapping.getMethod().getReturnType()==ModelAndView.class) {
         return (ModelAndView) object;
      }
      return null;
   }


   private Object caseStringValue (String value, Class<?> clazz) {
      if (clazz == String.class) {
         return value;
      } else if (clazz == Integer.class) {
         return Integer.valueOf(value);
      } else if (clazz == int.class) {
         return Integer.valueOf(value).intValue();
      } else {
         return null;
      }
   }



}
